package com.yesep.learn.design.creational.singleton;

/**
 * 单例模式（Singleton Pattern）是设计模式中一种常用的创建型模式，它确保一个类仅有一个实例，并提供一个全局访问点来获取该实例。在数学与逻辑学中，singleton定义为“有且仅有一个元素的集合”。在软件设计中，单例模式通过控制类的实例化过程，确保一个类只有一个实例，并且该实例易于被外界访问。这种模式常用于管理全局唯一的资源或服务，如数据库连接池、线程池、配置文件管理器等。
 * <p>
 * 单例模式的实现要点包括：
 * <p>
 * 私有化构造函数：防止外部通过new关键字直接实例化对象。
 * 提供全局访问点：通常是通过一个静态方法返回类的唯一实例。
 * 确保实例的唯一性：在整个应用程序生命周期中，单例类的实例只被创建一次。
 * 单例模式分类
 * 单例模式根据不同的实现方式和线程安全考虑，可以分为多种类型。常见的单例模式实现方式包括：
 * <p>
 * 饿汉式单例模式
 * 静态常量方式：在类加载时就完成了单例的初始化，因此类加载较慢，但获取对象的速度快。
 * 静态代码块方式：与静态常量方式类似，但实例的创建放在静态代码块中。
 * 优点：实现简单，无需考虑线程同步问题。
 * 缺点：如果单例对象较大，可能会浪费内存，因为它在类加载时就已创建。
 * 懒汉式单例模式
 * 线程不安全方式：在第一次调用getInstance()方法时才创建实例，但存在线程安全问题。
 * 线程安全方式（同步方法）：通过synchronized关键字保证线程安全，但效率较低，因为每次调用getInstance()都需要进行线程同步。
 * 双重检查锁方式：在懒汉式的基础上，通过双重检查锁机制优化性能，同时保证线程安全。需要注意的是，实例变量需要使用volatile关键字修饰，以防止指令重排。
 * 优点：实现了懒加载，并且在一定程度上保证了线程安全。
 * 缺点：实现相对复杂，且在某些情况下可能仍然需要额外的性能开销。
 * 静态内部类单例模式
 * 利用静态内部类的特性，实现懒加载和线程安全。当外部类被加载时，静态内部类并不会被加载，只有在调用getInstance()方法时，静态内部类才会被加载和初始化。
 * 优点：实现了懒加载和线程安全，且实现方式相对简洁。
 * 缺点：无显著缺点，是一种常用的单例实现方式。
 * 枚举单例模式
 * 将单例对象定义为一个枚举元素，利用枚举的特性自动实现序列化机制，防止反序列化重新创建新的对象，同时保证线程安全。
 * 优点：实现简单，自动支持序列化机制，绝对防止多次实例化。
 * 缺点：在某些特殊场景下，可能需要更复杂的逻辑处理。
 */
public class Main {
    public static void main(String[] args) {
        UnsafeThreadLazySingleton instance1 = UnsafeThreadLazySingleton.getInstance();
        SafeThreadLazySingleton instance2 = SafeThreadLazySingleton.getInstance();
        EagerSingleton instance3 = EagerSingleton.getInstance();
        DoubleCheckedLockLazySingleton instance4 = DoubleCheckedLockLazySingleton.getInstance();
        StaticInnerSingleton instance5 = StaticInnerSingleton.getInstance();
        EnumSingleton instance6 = EnumSingleton.INSTANCE;
        instance6.getTarget().sayHello("wang");
    }
}
